﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace XBeeLib
{
    //このコントロールはXBeeによるパケットモード通信用に利用します。
    public partial class XbeeSerialPortControlPanel : UserControl
    {
        public delegate void _16BitAddressRxPacketEventHandler(object sender, RX16BitPacket packet);
        public delegate void _64BitAddressRxPacketEventHandler(object sender, RX64BitPacket packet);
        public delegate void ATCommandResponsePacketEventHandler(object sender, ATCommandResponsePacket packet);
        public delegate void TransmitStatusPacketEventHandler(object sender, TransmitStatusPacket packet);
        public delegate void ModemStatusPacketEventHandler(object sender, ModemStatusPacket packet);
        /// <summary>
        /// 16ビットアドレスモードのパケットを受信したときに発生します。
        /// </summary>
        [Description("16ビットアドレスモードのパケットを受信したときに発生します。")]
        public event _16BitAddressRxPacketEventHandler _16BitDataPacketReceived = null;
        /// <summary>
        /// 64ビットアドレスモードのパケットを受信したときに発生します。
        /// </summary>
        [Description("64ビットアドレスモードのパケットを受信したときに発生します。")]
        public event _64BitAddressRxPacketEventHandler _64BitDataPacketReceived = null;
        /// <summary>
        /// ATコマンドパケットを受信したときに発生します。
        /// </summary>
        [Description("ATコマンドパケットを受信したときに発生したときに発生します。")]
        public event ATCommandResponsePacketEventHandler ATCommandPacketReceived = null;
        /// <summary>
        /// ModemStatusパケッを受信したときに発生します。
        /// </summary>
        [Description("ModemStatusパケッを受信したときに発生します。")]
        public event ModemStatusPacketEventHandler modemStatusPacketPacketReceived = null;
        /// <summary>
        /// COMポートに接続したときに発生します。
        /// </summary>
        [Description("COMポートに接続したときに発生します。")]
        public event EventHandler Connected = null;//接続成功
        /// <summary>
        /// COMポートを切断したときに発生します。
        /// </summary>
        [Description("COMポートを切断したときに発生します。")]
        public event EventHandler Disconnected = null;//切断成功
        /// <summary>
        /// 送信ステータスパケットを受信したときに発生します。
        /// </summary>
        [Description("送信ステータスパケットを受信したときに発生します。")]
        public event TransmitStatusPacketEventHandler TransmitStatusPacketReceived = null;//送信パケット失敗
        /// <summary>
        /// XBeeの受信パケットの識別IDの列挙体
        /// </summary>
        public enum XBeeRXCmdID : byte
        {
            ATCommandResponsePacket = 0x88,
            RemoteCommandResponsePacket = 0x97,
            ModemStatusPacket = 0x8A,
            TXStatusPacket = 0x89,
            RX64BitPacket = 0x80,
            RX16BitPacket = 0x81,
        }
        /// <summary>
        /// XBeeステータスメッセージ
        /// </summary>
        public enum ModemStatus : byte
        {
            HardwareReset = 0,
            WatchdogTimerReset = 1,
            Associated = 2,
            Disassociated = 3,
            SynchronizationLost = 4,
            CoordinatorRealignment = 5,
            CoordinatorStarted = 6
        }
        public struct ModemStatusPacket
        {
            public ModemStatus status;
        }
        /// <summary>
        /// 16ビットパケット受信時のオプション
        /// </summary>
        public enum RX16BitRequestPacketOptions : byte
        {
            AddressBroadcast = 0x01,
            PanBroadcast = 0x02
        }
        /// <summary>
        /// 64ビットパケット受信時のオプション
        /// </summary>
        public enum RX64BitRequestPacketOptions : byte
        {
            AddressBroadcast = 0x01,
            PanBroadcast = 0x02
        }
        /// <summary>
        /// 16ビットパケットの構造体
        /// </summary>
        public struct RX16BitPacket
        {
            /// <summary>
            /// 送信元アドレス
            /// </summary>
            public ushort address;
            /// <summary>
            /// 電波強度-dBm
            /// </summary>
            public byte rssi;
            public byte[] dataArray;//データ部
            /// <summary>
            /// 同PANID内ブロードキャスト
            /// </summary>
            public bool addressBroadcastFlag;
            /// <summary>
            /// 同CH内ブロードキャスト
            /// </summary>
            public bool panBroadcastFlag;
        }
        /// <summary>
        /// 64ビットパケットの構造体
        /// </summary>
        public struct RX64BitPacket
        {
            /// <summary>
            /// 送信元アドレス
            /// </summary>
            public UInt64 address;
            /// <summary>
            /// 電波強度-dBm
            /// </summary>
            public byte rssi;
            public byte[] dataArray;//データ部
            /// <summary>
            /// 同PANID内ブロードキャスト
            /// </summary>
            public bool addressBroadcastFlag;
            /// <summary>
            /// 同CH内ブロードキャスト
            /// </summary>
            public bool panBroadcastFlag;
        }

        public struct TransmitStatusPacket
        {
            public byte frameID;
            public TXStatusPacketStatus status;
        }
        /// <summary>
        /// TXStatusPacketのステータス一覧の列挙体
        /// </summary>
        public enum TXStatusPacketStatus : byte
        {
            /// <summary>
            /// 成功
            /// </summary>
            Success = 0,
            /// <summary>
            /// 確認未受信
            /// </summary>
            NoACKReceived = 1,
            /// <summary>
            /// CCAfailure
            /// </summary>
            CCAfailure = 2,
            /// <summary>
            /// Purged
            /// </summary>
            Purged = 3
        }
        /// <summary>
        /// XBeeの送信パケットの識別ID
        /// </summary>
        public enum XBeeTXCmdID : byte
        {
            TX64BitRequestPacket = 0x00,
            TX16BitRequestPacket = 0x01,
            ATCommand = 0x08,
            ATCommandQueueParameterValuePacket = 0x09,
            RemoteATCommandRequestPacket = 0x17,
        }
        /// <summary>
        /// 16ビットパケット送信時のオプション
        /// </summary>
        public enum XBeeTX16BitRequestPacketOptions : byte
        {
            /// <summary>
            /// 指定なし。
            /// </summary>
            None = 0x00,
            /// <summary>
            /// 応答確認無効
            /// </summary>
            DisableACK = 0x01,
            /// <summary>
            /// 全PANIDブロードキャスト
            /// </summary>
            SendPacketWithBroadcastPANID = 0x04
        }
        /// <summary>
        /// 64ビットパケット送信時のオプション
        /// </summary>
        public enum XBeeTX64BitRequestPacketOptions : byte
        {
            /// <summary>
            /// 指定なし
            /// </summary>
            None = 0x00,
            /// <summary>
            /// 応答確認無効
            /// </summary>
            DisableACK = 0x01,
            /// <summary>
            /// 全PANIDブロードキャスト
            /// </summary>
            SendPacketWithBroadcastPANID = 0x04//All other bits must be set to 0.
        }
        /// <summary>
        /// ATCommandResponsePacketの構造体
        /// </summary>
        public struct ATCommandResponsePacket
        {
            public byte frameID;
            public XBeeATCmd cmd;
            public ATCommandResponsePacketStatus status;
            public UInt32 parameter;
            public byte[] parameterArray;//パラメータの配列

        }
        public enum ATCommandResponsePacketStatus : byte
        {
            OK = 0,
            ERROR = 1,
            InvalidCommand = 2,
            InvalidParameter = 3
        }
        /// <summary>
        /// 受信処理のステートマシン用の列挙体
        /// </summary>
        enum XBeeReadState : byte
        {
            ReadHead,
            ReadDataSizeMSB,
            ReadDataSizeLSB,
            ReadData,
            ReadCheckSum
        }
        XBeeReadState readState;
        bool escapeFlag;
        byte[] frameDataArray = new byte[255];
        ushort frameSize;//パケットのデータ部のサイズ
        ushort frameGetedCnt;//受信したデータ部の長さ
        byte frameCheckSum;//
        byte frameID = 0;
        byte lastRssi = 0xFF;
        public int lastFifoBufBytes = 0;
        [Description("SerialPortのDataReceivedイベントを利用して処理をするかどうか示します。応答速度は上がるが、フリーズしやすくなる。")]
        [DefaultValue(true)]
        public bool UseSerialInterrupt { get; set; }
        [Description("受信バッファあふれ時、受信バッファを一度クリアするかどうか示します。")]
        [DefaultValue(true)]
        public bool ClearBufOnOverLoad { get; set; }
        [Description("受信バッファあふれ時、COMポートを自動的に閉じるかどうか示します。")]
        [DefaultValue(false)]
        public bool StopOnOverLoad { get; set; }
        public XbeeSerialPortControlPanel()
        {
            InitializeComponent();

            int serial_port_num = SerialPort.GetPortNames().Length;
            serialPort.Encoding = Encoding.ASCII;
            string[] com_ports = SerialPort.GetPortNames();
            foreach (string com_port in com_ports)
            {
                COMPortsComboBox.Items.Add(com_port);
            }
            if (serial_port_num != 0)
            {
                COMPortsComboBox.Text = com_ports[0];
            }
            this.Disposed += UnloadControl;//終了時の処理を追加
            UseSerialInterrupt = true;

        }
        private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            lock (serialPort)
            {
                try
                {

                    if (UseSerialInterrupt)
                    {
                        while (serialPort.BytesToRead != 0)
                        {
                            readSerialData((byte)serialPort.ReadByte());
                        }
                    }
                }
                catch
                {
                    addLogTextBeginInvoke("エラー:シリアルデータの読み出し処理中に例外エラーが発生しました。\r\n");
                }
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            rssiTextBox.Text = (0 - lastRssi).ToString();
            if (lastRssi <= 92)
            {
                rssiProgressBar.Value = 92 - lastRssi;
            }
            else
            {
                rssiProgressBar.Value = 0;
            }
            lock (serialPort)
            {
                if (!serialPort.IsOpen)
                    return;
                {
                    int readedCnt = 0;
                    int temp = serialPort.BytesToRead;
                    lastFifoBufBytes = temp;
                    byte[] tempData = new byte[temp];
                    serialPort.Read(tempData, 0, temp);
                    if (temp >= serialPort.ReadBufferSize - 100)//バッファサイズ通りに呼んでくれないことがあるので、ちょっといじってみた。
                    {
                        if (StopOnOverLoad)
                        {
                            serialPort.Close();
                            this.addLogText("処理落ちが発生したので切断しました。\n");
                            return;
                        }
                        else
                        {
                            if (ClearBufOnOverLoad)
                            {
                                this.addLogText("処理落ちが発生したのでバッファをクリアしました。\n");
                                return;
                            }
                        }
                    }
                    while (readedCnt != temp)
                    {
                        readSerialData(tempData[readedCnt]);
                        readedCnt++;
                    }
                }
            }
        }
        private void readSerialData(byte data)
        {

            if (data == 0x7e)
            {
                escapeFlag = false;
                if (readState != XBeeReadState.ReadHead)
                {
                    //エラー発生
                    addLogTextBeginInvoke("エラー:ヘッダ部が予期しないタイミングで届きました。\r\n");
                }
                readState = XBeeReadState.ReadDataSizeMSB;
                return;
            }
            else if (data == 0x7d)
            {
                escapeFlag = true;
                return;
            }
            if (escapeFlag)
            {
                data = (byte)(data ^ 0x20);
                escapeFlag = false;
            }

            switch (readState)
            {
                /*case XBeeReadState.ReadHead:
                    break;*/
                case XBeeReadState.ReadDataSizeMSB:
                    frameSize = (ushort)(data << 2);
                    readState = XBeeReadState.ReadDataSizeLSB;
                    break;
                case XBeeReadState.ReadDataSizeLSB:
                    frameSize = (ushort)(frameSize + data);
                    if (frameSize != 0)//正常時
                    {
                        frameGetedCnt = 0;
                        frameCheckSum = 0xFF;
                        readState = XBeeReadState.ReadData;
                    }
                    else//エラー時
                    {
                        addLogTextBeginInvoke("エラー:フレーム部のデータサイズが0です。\r\n");
                        readState = XBeeReadState.ReadHead;
                    }
                    break;
                case XBeeReadState.ReadData:
                    frameDataArray[frameGetedCnt] = data;
                    frameCheckSum -= data;
                    frameGetedCnt++;
                    if (frameGetedCnt == frameSize)
                    {
                        readState = XBeeReadState.ReadCheckSum;
                    }
                    break;
                case XBeeReadState.ReadCheckSum:
                    if (data == frameCheckSum)//正常時
                    {
                        byte[] geted_frame_data_array = new byte[frameSize];
                        Array.Copy(frameDataArray, geted_frame_data_array, frameSize);
                        readedPacket(geted_frame_data_array);
                    }
                    else//エラー
                    {
                        addLogTextBeginInvoke("エラー:チェックサムが合いませんでした。\r\n");
                    }
                    readState = XBeeReadState.ReadHead;
                    break;
            }
        }
        private void readedPacket(byte[] readData)
        {
            switch ((XBeeRXCmdID)readData[0])
            {
                case XBeeRXCmdID.RX16BitPacket:
                    if (readData.Length >= 6)
                    {
                        this.BeginInvoke((MethodInvoker)delegate
                        {
                            if (_16BitDataPacketReceived != null)
                            {
                                byte[] data_array = new byte[readData.Length - 5];
                                Array.Copy(readData, 5, data_array, 0, data_array.Length);
                                RX16BitPacket packetStruct = new RX16BitPacket();
                                packetStruct.address = (ushort)((readData[1] << 8) + readData[2]);
                                packetStruct.rssi = readData[3];
                                if ((readData[4] & (byte)RX16BitRequestPacketOptions.AddressBroadcast) != 0)
                                {
                                    packetStruct.addressBroadcastFlag = true;
                                }
                                else
                                {
                                    packetStruct.addressBroadcastFlag = false;
                                }
                                if ((readData[4] & (byte)RX16BitRequestPacketOptions.PanBroadcast) != 0)
                                {
                                    packetStruct.panBroadcastFlag = true;
                                }
                                else
                                {
                                    packetStruct.panBroadcastFlag = false;
                                }
                                packetStruct.dataArray = data_array;

                                _16BitDataPacketReceived(this, packetStruct);
                            }
                            lastRssi = readData[3];
                        });
                    }
                    else
                    {
                        addLogTextBeginInvoke("パケット長が異常です。RawReadData:" + BitConverter.ToString(readData) + "\r\n");
                    }
                    break;
                case XBeeRXCmdID.RX64BitPacket:
                    if (readData.Length >= 12)
                    {

                        this.BeginInvoke((MethodInvoker)delegate
                        {
                            if (_64BitDataPacketReceived != null)
                            {
                                byte[] data_array = new byte[readData.Length - 11];
                                Array.Copy(readData, 11, data_array, 0, data_array.Length);
                                RX64BitPacket packetStruct = new RX64BitPacket();
                                packetStruct.address = (UInt64)(
                                    ((UInt64)readData[1] << 56) +
                                    ((UInt64)readData[2] << 48) +
                                    ((UInt64)readData[3] << 40) +
                                    ((UInt64)readData[4] << 32) +
                                    ((UInt64)readData[5] << 24) +
                                    ((UInt64)readData[6] << 16) +
                                    ((UInt64)readData[7] << 8) +
                                    ((UInt64)readData[8] << 0));
                                packetStruct.rssi = readData[9];
                                if ((readData[10] & (byte)RX64BitRequestPacketOptions.AddressBroadcast) != 0)
                                {
                                    packetStruct.addressBroadcastFlag = true;
                                }
                                if ((readData[10] & (byte)RX64BitRequestPacketOptions.PanBroadcast) != 0)
                                {
                                    packetStruct.panBroadcastFlag = true;
                                }
                                packetStruct.dataArray = data_array;
                                _64BitDataPacketReceived(this, packetStruct);

                            }
                            lastRssi = readData[9];
                        });
                    }
                    else
                    {
                        addLogTextBeginInvoke("パケット長が異常です。RawReadData:" + BitConverter.ToString(readData) + "\r\n");
                    }
                    break;
                case XBeeRXCmdID.TXStatusPacket:
                    TransmitStatusPacket statusPacket;
                    statusPacket.frameID = readData[1];
                    statusPacket.status = (TXStatusPacketStatus)readData[2];
                    if (TransmitStatusPacketReceived != null)
                    {
                        this.BeginInvoke((MethodInvoker)delegate
                        {
                            TransmitStatusPacketReceived(this, statusPacket);

                        });
                    }
                    break;
                case XBeeRXCmdID.RemoteCommandResponsePacket:
                    addLogTextBeginInvoke("警告:未実装であるパケットが受信されました。\r\n" + XBeeRXCmdID.RemoteCommandResponsePacket.ToString());
                    addLogTextBeginInvoke("RawReadData:" + BitConverter.ToString(readData) + "\r\n");
                    break;
                case XBeeRXCmdID.ModemStatusPacket:
                    if (readData.Length >= 2)
                    {
                        if (modemStatusPacketPacketReceived != null)
                        {
                            ModemStatusPacket packet;
                            packet.status = (ModemStatus)readData[1];
                            this.BeginInvoke((MethodInvoker)delegate
                            {
                                modemStatusPacketPacketReceived(this, packet);

                            });
                        }
                    }
                    break;
                case XBeeRXCmdID.ATCommandResponsePacket:
                    if (readData.Length >= 5)
                    {
                        if (ATCommandPacketReceived != null)
                        {
                            this.BeginInvoke((MethodInvoker)delegate
                            {
                                ATCommandResponsePacket packet;
                                packet.parameterArray = new byte[readData.Length - 5];
                                Array.Copy(readData, 5, packet.parameterArray, 0, packet.parameterArray.Length);
                                packet.cmd = (XBeeATCmd)((readData[2] << 8) + readData[3]);
                                packet.frameID = readData[1];
                                packet.status = (ATCommandResponsePacketStatus)readData[4];
                                switch (readData.Length - 5)
                                {
                                    case 0:
                                        packet.parameter = 0;
                                        break;
                                    case 1:
                                        packet.parameter = (UInt32)readData[5];
                                        break;
                                    case 2:
                                        packet.parameter = ((UInt32)readData[5] << 8) + (UInt32)readData[6];
                                        break;
                                    case 3:
                                        packet.parameter = ((UInt32)readData[5] << 16) + ((UInt32)readData[6] << 8) + (UInt32)readData[7];
                                        break;
                                    case 4:
                                        packet.parameter = ((UInt32)readData[5] << 24) + ((UInt32)readData[6] << 16) + ((UInt32)readData[7] << 8) + (UInt32)readData[8];
                                        break;
                                    default:
                                        packet.parameter = 0;
                                        break;

                                }
                                ATCommandPacketReceived(this, packet);

                            });
                        }
                    }
                    break;
                default:
                    addLogTextBeginInvoke("定義されていないパケットが受信されました。\r\n");
                    addLogTextBeginInvoke("RawReadData:" + BitConverter.ToString(readData) + "\r\n");
                    break;
            }

        }

        /// <summary>
        /// 16ビットアドレスモードでパケットを送信する関数
        /// </summary>
        /// <param name="address"></param>
        /// <param name="data"></param>
        public byte send16BitAddressTxPacket(ushort address, byte[] data)
        {
            return send16BitAddressTxPacket(address, data, XBeeTX16BitRequestPacketOptions.None);
        }
        /// <summary>
        /// 16ビットアドレスモードでパケットを送信する関数
        /// </summary>
        /// <param name="address"></param>
        /// <param name="data"></param>
        public byte send16BitAddressTxPacket(ushort address, byte[] data,XBeeTX16BitRequestPacketOptions option)
        {
            System.Collections.ArrayList sendDataList = new System.Collections.ArrayList();
            byte check_sum = 0xFF;
            ushort frame_size = (ushort)(5 + data.Length);
            byte frameID;
            frameID = getTxFrameID();
            if (data.Length > 100)
            {
                throw new ArgumentOutOfRangeException();//送信パケット長が長すぎる。
            }
            //ヘッダ部
            sendDataList.Add((byte)0x7e);//ヘッダ部開始
            sendDataList.Add((byte)(frame_size >> 8));//Length,MSB
            sendDataList.Add((byte)(frame_size & 0xFF));//Length,LSB
            //データ部
            //データ部(送信用ヘッダ)
            sendDataList.Add((byte)(XBeeTXCmdID.TX16BitRequestPacket));//APIIdentifier
            sendDataList.Add((byte)(frameID));//FrameID
            sendDataList.Add((byte)(address >> 8));//DestinationAddress,MSB
            sendDataList.Add((byte)(address & 0xFF));//DestinationAddress,LSB
            sendDataList.Add((byte)(option));//Options
            //データ部(データ本体)
            for (int i = 0; i < data.Length; i++)
            {
                sendDataList.Add(data[i]);
            }
            //チャックサムの算出
            for (int i = 0; i < data.Length + 5; i++)
            {
                check_sum -= (byte)sendDataList[3 + i];
            }
            sendDataList.Add(check_sum);
            SendXBeeWithEscape(sendDataList);
            return frameID;
        }

        /// <summary>
        /// 64ビットアドレスモードでパケットを送信する関数
        /// 0xFFFFの場合、同PANID内ブロードキャスト
        /// </summary>
        public byte send64BitAddressTxPacket(UInt64 address, byte[] data)
        {
            return send64BitAddressTxPacket(address, data, XBeeTX64BitRequestPacketOptions.None);
        }
        /// <summary>
        /// 64ビットアドレスモードでパケットを送信する関数
        /// 0xFFFFの場合、同PANID内ブロードキャスト
        /// </summary>
        public byte send64BitAddressTxPacket(UInt64 address, byte[] data, XBeeTX64BitRequestPacketOptions option)
        {
            System.Collections.ArrayList sendDataList = new System.Collections.ArrayList();
            byte check_sum = 0xFF;
            ushort frame_size = (ushort)(11 + data.Length);
            byte frameID;
            frameID = getTxFrameID();
            if (data.Length > 100)
            {
                throw new ArgumentOutOfRangeException();//送信パケット長が長すぎる。
            }
            //ヘッダ部
            sendDataList.Add((byte)0x7e);//ヘッダ部開始
            sendDataList.Add((byte)(frame_size >> 8));//Length,MSB
            sendDataList.Add((byte)(frame_size & 0xFF));//Length,LSB
            //データ部
            //データ部(送信用ヘッダ)
            sendDataList.Add((byte)(XBeeTXCmdID.TX64BitRequestPacket));//APIIdentifier
            sendDataList.Add((byte)(frameID));//FrameID
            sendDataList.Add((byte)(address >> 56));
            sendDataList.Add((byte)(address >> 48));
            sendDataList.Add((byte)(address >> 40));
            sendDataList.Add((byte)(address >> 32));
            sendDataList.Add((byte)(address >> 24));
            sendDataList.Add((byte)(address >> 16));
            sendDataList.Add((byte)(address >> 8));
            sendDataList.Add((byte)(address >> 0));
            sendDataList.Add((byte)(option));//Options
            //データ部(データ本体)
            for (int i = 0; i < data.Length; i++)
            {
                sendDataList.Add(data[i]);
            }
            //チャックサムの算出
            for (int i = 0; i < data.Length + 11; i++)
            {
                check_sum -= (byte)sendDataList[3 + i];
            }
            sendDataList.Add(check_sum);
            SendXBeeWithEscape(sendDataList);
            return frameID;
        }

        /// <summary>
        /// ATコマンドを送信する関数
        /// </summary>
        public byte sendAtCommand(byte[] data)
        {
            System.Collections.ArrayList sendDataList = new System.Collections.ArrayList();
            byte check_sum = 0xFF;
            ushort frame_size = (ushort)(2 + data.Length);
            byte frameID;
            frameID = getTxFrameID();
            if (data.Length > 100)
            {
                throw new ArgumentOutOfRangeException();//送信パケット長が長すぎる。
            }
            //ヘッダ部
            sendDataList.Add((byte)0x7e);//ヘッダ部開始
            sendDataList.Add((byte)(frame_size >> 8));//Length,MSB
            sendDataList.Add((byte)(frame_size & 0xFF));//Length,LSB
            //データ部
            //データ部(送信用ヘッダ)
            sendDataList.Add((byte)(XBeeTXCmdID.ATCommand));//APIIdentifier
            sendDataList.Add((byte)(frameID));//FrameID
            //データ部(データ本体)
            for (int i = 0; i < data.Length; i++)
            {
                sendDataList.Add(data[i]);
            }
            //チャックサムの算出
            for (int i = 0; i < data.Length + 2; i++)
            {
                check_sum -= (byte)sendDataList[3 + i];
            }
            sendDataList.Add(check_sum);
            SendXBeeWithEscape(sendDataList);
            return frameID;
        }
        private void SendXBeeWithEscape(System.Collections.ArrayList sendDataList)
        {
            int esc_cnt = 1;
            while (true)
            {
                if ((byte)sendDataList[esc_cnt] == 0x7E ||
                    (byte)sendDataList[esc_cnt] == 0x7D ||
                    (byte)sendDataList[esc_cnt] == 0x11 ||
                    (byte)sendDataList[esc_cnt] == 0x13
                    )
                {
                    sendDataList.Insert(esc_cnt, (byte)0x7D);
                    sendDataList[esc_cnt + 1] = (byte)((byte)(sendDataList[esc_cnt + 1]) ^ 0x20);
                    esc_cnt += 2;//エスケープ文字を含めるため2インクリメント
                }
                else
                {
                    esc_cnt++;//インクリメント
                }
                if (esc_cnt >= sendDataList.Count)
                {
                    break;
                }
            }
            byte[] sendDataArray = (byte[])sendDataList.ToArray(typeof(byte));
            lock (serialPort)
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Write(sendDataArray, 0, sendDataArray.Length);
                }
                else
                {
                    addLogText("エラー:接続していません。\n");
                }
            }
        }
        private void Connection_button_Click(object sender, EventArgs e)
        {
            lock (serialPort)
            {
                if (serialPort.IsOpen == false)
                {

                    log_text_box.AppendText(COMPortsComboBox.Text + "に接続中です。\r\n");
                    try
                    {
                        serialPort.PortName = COMPortsComboBox.Text;
                        try
                        {
                            serialPort.BaudRate = int.Parse(FlowRateComboBox.Text);
                        }
                        catch
                        {
                            log_text_box.AppendText("通信速度が異常です。\r\n");
                        }
                        serialPort.Open();
                        log_text_box.AppendText("接続しました。\r\n");
                        if (Connected != null)
                        {
                            Connected(serialPort, null);
                        }
                    }
                    catch
                    {
                        log_text_box.AppendText("接続中にエラーが発生しました。\r\n");

                    }

                }
                else
                {
                    addLogText("すでに接続しています。\n");
                }
            }
        }

        private void disconnection_button_Click(object sender, EventArgs e)
        {
            lock (serialPort)
            {
                if (serialPort.IsOpen == true)
                {
                    try
                    {
                        serialPort.Close();
                        log_text_box.AppendText(serialPort.PortName + "を切断しました。\r\n");
                        if (Disconnected != null)
                        {
                            Disconnected(serialPort, null);
                        }
                    }
                    catch
                    {
                        log_text_box.AppendText(serialPort.PortName + "の切断中にエラーが発生しました。\r\n");
                    }

                }
                else
                {
                    log_text_box.AppendText("すでに切断しています。\n");
                }
            }
        }
        public void disconnectSerialPort()
        {
            lock (serialPort)
            {
                if (serialPort.IsOpen == true)
                {
                    try
                    {
                        serialPort.Close();
                        if (Disconnected != null)
                        {
                            Disconnected(serialPort, null);
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }
        private void addLogTextBeginInvoke(string text)
        {
            try
            {
                this.BeginInvoke((MethodInvoker)delegate
                {
                    log_text_box.AppendText(text);
                });
            }
            catch
            {
            }
        }
        /// <summary>
        /// コントロール内のテキストボックスにテキストを追加する関数
        /// </summary>
        /// <param name="text"></param>
        public void addLogText(string text)
        {
            log_text_box.AppendText(text);
        }
        void UnloadControl(object sender, EventArgs e)
        {
            /*シリアルのクローズ処理は自動的に実行されるみたいなのでコメントアウト
            if (serialPort.IsOpen == true)
            {
                try
                {
                    serialPort.Close();
                    MessageBox.Show("comポートのクローズ処理を実行しました。");
                }
                catch
                {
                    MessageBox.Show("comポートのクローズ処理中にエラーが発生しました。");
                }
            }*/
        }

        private void clear_log_button_Click(object sender, EventArgs e)
        {
            log_text_box.Text = "";
        }

        private void log_save_button_Click(object sender, EventArgs e)
        {
        }
        private byte getTxFrameID()
        {
            frameID++;
            if (frameID == 0)
            {
                frameID = 1;
            }
            return frameID;
        }
        public byte[] CreateATCommandData(char atCmd1, char atCmd2)
        {
            byte[] data = new byte[2];
            data[0] = (byte)(atCmd1);
            data[1] = (byte)(atCmd2);
            return data;
        }
        public byte[] CreateATCommandData(char atCmd1, char atCmd2, byte[] parameter)
        {
            byte[] data = new byte[parameter.Length + 2];
            data[0] = (byte)(atCmd1);
            data[1] = (byte)(atCmd2);
            for (int i = 0; i < parameter.Length; i++)
            {
                data[i + 2] = parameter[i];
            }
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmd atCmd)
        {
            byte[] data = new byte[2];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmdReadOnly atCmd)
        {
            byte[] data = new byte[2];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmd1byte atCmd)
        {
            byte[] data = new byte[2];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmd2byte atCmd)
        {
            byte[] data = new byte[2];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmd4byte atCmd)
        {
            byte[] data = new byte[2];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmd atCmd, byte parameter)
        {
            byte[] data = new byte[3];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            data[2] = parameter;
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmd atCmd, UInt16 parameter)
        {
            byte[] data = new byte[4];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            data[2] = (byte)((int)parameter >> 8);
            data[3] = (byte)((int)parameter >> 0);
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmd atCmd, UInt32 parameter)
        {
            byte[] data = new byte[6];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            data[2] = (byte)((int)parameter >> 24);
            data[3] = (byte)((int)parameter >> 16);
            data[4] = (byte)((int)parameter >> 8);
            data[5] = (byte)((int)parameter >> 0);
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmd atCmd, byte[] parameter)
        {
            byte[] data = new byte[parameter.Length + 2];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            for (int i = 0; i < parameter.Length; i++)
            {
                data[i + 2] = parameter[i];
            }
            return data;
        }

        public byte[] CreateATCommandData(XBeeATCmd1byte atCmd, byte parameter)
        {
            byte[] data = new byte[3];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            data[2] = parameter;
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmd2byte atCmd, UInt16 parameter)
        {
            byte[] data = new byte[4];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            data[2] = (byte)((int)parameter >> 8);
            data[3] = (byte)((int)parameter >> 0);
            return data;
        }
        public byte[] CreateATCommandData(XBeeATCmd4byte atCmd, UInt32 parameter)
        {
            byte[] data = new byte[6];
            data[0] = (byte)((int)atCmd >> 8);
            data[1] = (byte)((int)atCmd >> 0);
            data[2] = (byte)((int)parameter >> 24);
            data[3] = (byte)((int)parameter >> 16);
            data[4] = (byte)((int)parameter >> 8);
            data[5] = (byte)((int)parameter >> 0);
            return data;
        }

    }
    /// <summary>
    /// 書込専用なATコマンド
    /// </summary>
    public enum XBeeATCmdSetOnly : ushort
    {
        /// <summary>
        /// ATWRコマンド,Write
        /// </summary>
        WR = (ushort)(('W' << 8) + 'R'),
        /// <summary>
        /// ATREコマンド
        /// </summary>
        RE = (ushort)(('R' << 8) + 'E'),
        /// <summary>
        /// ATFRコマンド
        /// </summary>
        FR = (ushort)(('F' << 8) + 'R'),
        /// <summary>
        /// ATAIコマンド
        /// </summary>
        AI = (ushort)(('A' << 8) + 'I'),
        /// <summary>
        /// ATDAコマンド
        /// </summary>
        DA = (ushort)(('D' << 8) + 'A'),
        /// <summary>
        /// ATFPコマンド,Software Reset
        /// </summary>
        FP = (ushort)(('F' << 8) + 'P'),
        /// <summary>
        /// ATASコマンド,Active Scan
        /// </summary>
        AS = (ushort)(('A' << 8) + 'S'),
        /// <summary>
        /// ATEDコマンド,Energy Scan
        /// </summary>
        ED = (ushort)(('E' << 8) + 'D'),
        /// <summary>
        /// ATIOコマンド
        /// </summary>
        IO = (ushort)(('I' << 8) + 'O'),
        /// <summary>
        /// ATCNコマンド
        /// </summary>
        CN = (ushort)(('C' << 8) + 'N'),
        /// <summary>
        /// ATACコマンド
        /// </summary>
        AC = (ushort)(('A' << 8) + 'C'),
    }
    /// <summary>
    /// 読出専用なATコマンド
    /// </summary>
    public enum XBeeATCmdReadOnly : ushort
    {
        /// <summary>
        /// ATSHコマンド
        /// </summary>
        SH = (ushort)(('S' << 8) + 'H'),
        /// <summary>
        /// ATSLコマンド
        /// </summary>
        SL = (ushort)(('S' << 8) + 'L'),
        /// <summary>
        /// ATISコマンド
        /// </summary>
        IS = (ushort)(('I' << 8) + 'S'),
        /// <summary>
        /// ATVRコマンド
        /// </summary>
        VR = (ushort)(('V' << 8) + 'R'),
        //VL = (ushort)(('V' << 8) + 'L'),//エラーが帰ってくるので封印
        /// <summary>
        /// ATHVコマンド
        /// </summary>
        HV = (ushort)(('H' << 8) + 'V'),
        /// <summary>
        /// ATDBコマンド
        /// </summary>
        DB = (ushort)(('D' << 8) + 'B'),
    }
    /// <summary>
    /// 書込、読出可能な1バイトATコマンド
    /// </summary>
    public enum XBeeATCmd1byte : ushort
    {
        /// <summary>
        /// ATCHコマンド
        /// </summary>
        CH = (ushort)(('C' << 8) + 'H'),
        /// <summary>
        /// ATRRコマンド
        /// </summary>
        RR = (ushort)(('R' << 8) + 'R'),
        /// <summary>
        /// ATRNコマンド
        /// </summary>
        RN = (ushort)(('R' << 8) + 'N'),
        /// <summary>
        /// ATMMコマンド
        /// </summary>
        MM = (ushort)(('M' << 8) + 'M'),
        /// <summary>
        /// ATNTコマンド
        /// </summary>
        NT = (ushort)(('N' << 8) + 'T'),
        /// <summary>
        /// ATNOコマンド
        /// </summary>
        NO = (ushort)(('N' << 8) + 'O'),
        /// <summary>
        /// ATCEコマンド
        /// </summary>
        CE = (ushort)(('C' << 8) + 'E'),
        /// <summary>
        /// ATSDコマンド
        /// </summary>
        SD = (ushort)(('S' << 8) + 'D'),
        /// <summary>
        /// ATA1コマンド
        /// </summary>
        A1 = (ushort)(('A' << 8) + '1'),
        /// <summary>
        /// ATA2コマンド
        /// </summary>
        A2 = (ushort)(('A' << 8) + '2'),
        /// <summary>
        /// ATEEコマンド
        /// </summary>
        EE = (ushort)(('E' << 8) + 'E'),
        /// <summary>
        /// ATPLコマンド
        /// </summary>
        PL = (ushort)(('P' << 8) + 'L'),
        /// <summary>
        /// ATCAコマンド
        /// </summary>
        CA = (ushort)(('C' << 8) + 'A'),
        /// <summary>
        /// ATSMコマンド
        /// </summary>
        SM = (ushort)(('S' << 8) + 'M'),
        /// <summary>
        /// ATSOコマンド
        /// </summary>
        SO = (ushort)(('S' << 8) + 'O'),
        /// <summary>
        /// ATBDコマンド
        /// </summary>
        BD = (ushort)(('B' << 8) + 'D'),
        /// <summary>
        /// ATROコマンド
        /// </summary>
        RO = (ushort)(('R' << 8) + 'O'),
        /// <summary>
        /// ATAPコマンド
        /// </summary>
        AP = (ushort)(('A' << 8) + 'P'),
        /// <summary>
        /// ATNBコマンド
        /// </summary>
        NB = (ushort)(('N' << 8) + 'B'),
        /// <summary>
        /// ATPRコマンド
        /// </summary>
        PR = (ushort)(('P' << 8) + 'R'),
        /// <summary>
        /// ATD8コマンド
        /// </summary>
        D8 = (ushort)(('D' << 8) + '8'),
        /// <summary>
        /// ATD7コマンド
        /// </summary>
        D7 = (ushort)(('D' << 8) + '7'),
        /// <summary>
        /// ATD6コマンド
        /// </summary>
        D6 = (ushort)(('D' << 8) + '6'),
        /// <summary>
        /// ATD5コマンド
        /// </summary>
        D5 = (ushort)(('D' << 8) + '5'),
        /// <summary>
        /// ATD4コマンド
        /// </summary>
        D4 = (ushort)(('D' << 8) + '4'),
        /// <summary>
        /// ATD3コマンド
        /// </summary>
        D3 = (ushort)(('D' << 8) + '3'),
        /// <summary>
        /// ATD2コマンド
        /// </summary>
        D2 = (ushort)(('D' << 8) + '2'),
        /// <summary>
        /// ATD1コマンド
        /// </summary>
        D1 = (ushort)(('D' << 8) + '1'),
        /// <summary>
        /// ATD0コマンド
        /// </summary>
        D0 = (ushort)(('D' << 8) + '0'),
        /// <summary>
        /// ATIUコマンド
        /// </summary>
        IU = (ushort)(('I' << 8) + 'U'),
        /// <summary>
        /// ATITコマンド
        /// </summary>
        IT = (ushort)(('I' << 8) + 'T'),
        /// <summary>
        /// ATICコマンド
        /// </summary>
        IC = (ushort)(('I' << 8) + 'C'),
        /// <summary>
        /// ATT7コマンド
        /// </summary>
        T7 = (ushort)(('T' << 8) + '7'),
        /// <summary>
        /// ATT6コマンド
        /// </summary>
        T6 = (ushort)(('T' << 8) + '6'),
        /// <summary>
        /// ATT5コマンド
        /// </summary>
        T5 = (ushort)(('T' << 8) + '5'),
        /// <summary>
        /// ATT4コマンド
        /// </summary>
        T4 = (ushort)(('T' << 8) + '4'),
        /// <summary>
        /// ATT3コマンド
        /// </summary>
        T3 = (ushort)(('T' << 8) + '3'),
        /// <summary>
        /// ATT2コマンド
        /// </summary>
        T2 = (ushort)(('T' << 8) + '2'),
        /// <summary>
        /// ATT1コマンド
        /// </summary>
        T1 = (ushort)(('T' << 8) + '1'),
        /// <summary>
        /// ATT0コマンド
        /// </summary>
        T0 = (ushort)(('T' << 8) + '0'),
        /// <summary>
        /// ATP0コマンド
        /// </summary>
        P0 = (ushort)(('P' << 8) + '0'),
        /// <summary>
        /// ATP1コマンド
        /// </summary>
        P1 = (ushort)(('P' << 8) + '1'),
        /// <summary>
        /// ATPTコマンド
        /// </summary>
        PT = (ushort)(('P' << 8) + 'T'),
        /// <summary>
        /// ATRPコマンド
        /// </summary>
        RP = (ushort)(('R' << 8) + 'P'),
        /// <summary>
        /// ATDBコマンド
        /// </summary>
        DB = (ushort)(('D' << 8) + 'B'),
        /// <summary>
        /// ATCCコマンド
        /// </summary>
        CC = (ushort)(('C' << 8) + 'C')
    }
    /// <summary>
    /// 書込、読出可能な2バイトATコマンド
    /// </summary>
    public enum XBeeATCmd2byte : ushort
    {
        /// <summary>
        /// ATIDコマンド
        /// </summary>
        ID = (ushort)(('I' << 8) + 'D'),
        /// <summary>
        /// ATMYコマンド
        /// </summary>
        MY = (ushort)(('M' << 8) + 'Y'),
        /// <summary>
        /// ATCEコマンド
        /// </summary>
        CE = (ushort)(('C' << 8) + 'E'),
        /// <summary>
        /// ATSCコマンド
        /// </summary>
        SC = (ushort)(('S' << 8) + 'C'),
        /// <summary>
        /// ATSTコマンド
        /// </summary>
        ST = (ushort)(('S' << 8) + 'T'),
        /// <summary>
        /// ATSPコマンド
        /// </summary>
        SP = (ushort)(('S' << 8) + 'P'),
        /// <summary>
        /// ATDPコマンド
        /// </summary>
        DP = (ushort)(('D' << 8) + 'P'),
        /// <summary>
        /// ATIRコマンド
        /// </summary>
        IR = (ushort)(('I' << 8) + 'R'),
        //M0 = (ushort)(('M' << 8) + '0'),//返答データが帰ってこない・・・
        //M1 = (ushort)(('M' << 8) + '1'),//返答データが帰ってこない・・・
        /// <summary>
        /// ATECコマンド
        /// </summary>
        EC = (ushort)(('E' << 8) + 'C'),
        /// <summary>
        /// ATEAコマンド
        /// </summary>
        EA = (ushort)(('E' << 8) + 'A'),
        /// <summary>
        /// ATCTコマンド
        /// </summary>
        CT = (ushort)(('C' << 8) + 'T'),
        /// <summary>
        /// ATGTコマンド
        /// </summary>
        GT = (ushort)(('G' << 8) + 'T'),
    }
    /// <summary>
    /// 書込、読出可能な4バイトATコマンド
    /// </summary>
    public enum XBeeATCmd4byte : ushort
    {
        /// <summary>
        /// ATDHコマンド
        /// </summary>
        DH = (ushort)(('D' << 8) + 'H'),
        /// <summary>
        /// ATDLコマンド
        /// </summary>
        DL = (ushort)(('D' << 8) + 'L'),
    }
    /// <summary>
    /// 全ATコマンドの列挙体
    /// </summary>
    public enum XBeeATCmd : ushort
    {
        //NONE = 0,
        /// <summary>
        /// ATWRコマンド
        /// 設定を不揮発性メモリに書込みます。
        /// </summary>
        WR = (ushort)(('W' << 8) + 'R'),
        /// <summary>
        /// ATREコマンド
        /// 設定をリセットします。
        /// </summary>
        RE = (ushort)(('R' << 8) + 'E'),
        /// <summary>
        /// ATFRコマンド
        /// XBeeをリセットします。
        /// </summary>
        FR = (ushort)(('F' << 8) + 'R'),
        /// <summary>
        /// ATCHコマンド
        /// 無線チャンネルの設定します。
        /// </summary>
        CH = (ushort)(('C' << 8) + 'H'),
        /// <summary>
        /// ATIDコマンド
        /// PANIDの設定をします。
        /// </summary>
        ID = (ushort)(('I' << 8) + 'D'),
        /// <summary>
        /// ATDHコマンド
        /// </summary>
        DH = (ushort)(('D' << 8) + 'H'),
        /// <summary>
        /// ATDLコマンド
        /// </summary>
        DL = (ushort)(('D' << 8) + 'L'),
        /// <summary>
        /// ATMYコマンド
        /// </summary>
        MY = (ushort)(('M' << 8) + 'Y'),
        /// <summary>
        /// ATSHコマンド
        /// </summary>
        SH = (ushort)(('S' << 8) + 'H'),
        /// <summary>
        /// ATSLコマンド
        /// </summary>
        SL = (ushort)(('S' << 8) + 'L'),
        /// <summary>
        /// ATRRコマンド
        /// </summary>
        RR = (ushort)(('R' << 8) + 'R'),
        /// <summary>
        /// ATRNコマンド
        /// </summary>
        RN = (ushort)(('R' << 8) + 'N'),
        /// <summary>
        /// ATMMコマンド
        /// </summary>
        MM = (ushort)(('M' << 8) + 'M'),
        /// <summary>
        /// ATNIコマンド
        /// </summary>
        NI = (ushort)(('N' << 8) + 'I'),
        /// <summary>
        /// ATNDコマンド
        /// </summary>
        ND = (ushort)(('N' << 8) + 'D'),
        /// <summary>
        /// ATNTコマンド
        /// </summary>
        NT = (ushort)(('N' << 8) + 'T'),
        /// <summary>
        /// ATNOコマンド
        /// </summary>
        NO = (ushort)(('N' << 8) + 'O'),
        /// <summary>
        /// ATDNコマンド
        /// </summary>
        DN = (ushort)(('D' << 8) + 'N'),
        /// <summary>
        /// ATCEコマンド
        /// </summary>
        CE = (ushort)(('C' << 8) + 'E'),
        /// <summary>
        /// ATSCコマンド
        /// </summary>
        SC = (ushort)(('S' << 8) + 'C'),
        /// <summary>
        /// ATSDコマンド
        /// </summary>
        SD = (ushort)(('S' << 8) + 'D'),
        /// <summary>
        /// ATA1コマンド
        /// </summary>
        A1 = (ushort)(('A' << 8) + '1'),
        /// <summary>
        /// ATA2コマンド
        /// </summary>
        A2 = (ushort)(('A' << 8) + '2'),
        /// <summary>
        /// ATAIコマンド
        /// </summary>
        AI = (ushort)(('A' << 8) + 'I'),
        /// <summary>
        /// ATDAコマンド
        /// </summary>
        DA = (ushort)(('D' << 8) + 'A'),
        /// <summary>
        /// ATFPコマンド
        /// </summary>
        FP = (ushort)(('F' << 8) + 'P'),
        /// <summary>
        /// ATASコマンド
        /// </summary>
        AS = (ushort)(('A' << 8) + 'S'),
        /// <summary>
        /// ATEDコマンド
        /// </summary>
        ED = (ushort)(('E' << 8) + 'D'),
        /// <summary>
        /// ATEEコマンド
        /// </summary>
        EE = (ushort)(('E' << 8) + 'E'),
        /// <summary>
        /// ATPLコマンド
        /// </summary>
        PL = (ushort)(('P' << 8) + 'L'),
        /// <summary>
        /// ATCAコマンド
        /// </summary>
        CA = (ushort)(('C' << 8) + 'A'),
        /// <summary>
        /// ATKYコマンド
        /// </summary>
        KY = (ushort)(('K' << 8) + 'Y'),
        /// <summary>
        /// ATSMコマンド
        /// </summary>
        SM = (ushort)(('S' << 8) + 'M'),
        /// <summary>
        /// ATSOコマンド
        /// </summary>
        SO = (ushort)(('S' << 8) + 'O'),
        /// <summary>
        /// ATSTコマンド
        /// </summary>
        ST = (ushort)(('S' << 8) + 'T'),
        /// <summary>
        /// ATSPコマンド
        /// </summary>
        SP = (ushort)(('S' << 8) + 'P'),
        /// <summary>
        /// ATDPコマンド
        /// </summary>
        DP = (ushort)(('D' << 8) + 'P'),
        /// <summary>
        /// ATBDコマンド
        /// </summary>
        BD = (ushort)(('B' << 8) + 'D'),
        /// <summary>
        /// ATROコマンド
        /// </summary>
        RO = (ushort)(('R' << 8) + 'O'),
        /// <summary>
        /// ATAPコマンド
        /// </summary>
        AP = (ushort)(('A' << 8) + 'P'),
        /// <summary>
        /// ATNBコマンド
        /// </summary>
        NB = (ushort)(('N' << 8) + 'B'),
        /// <summary>
        /// ATPRコマンド
        /// </summary>
        PR = (ushort)(('P' << 8) + 'R'),
        /// <summary>
        /// ATD8コマンド
        /// </summary>
        D8 = (ushort)(('D' << 8) + '8'),
        /// <summary>
        /// ATD7コマンド
        /// </summary>
        D7 = (ushort)(('D' << 8) + '7'),
        /// <summary>
        /// ATD6コマンド
        /// </summary>
        D6 = (ushort)(('D' << 8) + '6'),
        /// <summary>
        /// ATD5コマンド
        /// </summary>
        D5 = (ushort)(('D' << 8) + '5'),
        /// <summary>
        /// ATD4コマンド
        /// </summary>
        D4 = (ushort)(('D' << 8) + '4'),
        /// <summary>
        /// ATD3コマンド
        /// </summary>
        D3 = (ushort)(('D' << 8) + '3'),
        /// <summary>
        /// ATD2コマンド
        /// </summary>
        D2 = (ushort)(('D' << 8) + '2'),
        /// <summary>
        /// ATD1コマンド
        /// </summary>
        D1 = (ushort)(('D' << 8) + '1'),
        /// <summary>
        /// ATD0コマンド
        /// </summary>
        D0 = (ushort)(('D' << 8) + '0'),
        /// <summary>
        /// ATIUコマンド
        /// </summary>
        IU = (ushort)(('I' << 8) + 'U'),
        /// <summary>
        /// ATITコマンド
        /// </summary>
        IT = (ushort)(('I' << 8) + 'T'),
        /// <summary>
        /// ATISコマンド
        /// </summary>
        IS = (ushort)(('I' << 8) + 'S'),
        /// <summary>
        /// ATIOコマンド
        /// </summary>
        IO = (ushort)(('I' << 8) + 'O'),
        /// <summary>
        /// ATICコマンド
        /// </summary>
        IC = (ushort)(('I' << 8) + 'C'),
        /// <summary>
        /// ATIRコマンド
        /// </summary>
        IR = (ushort)(('I' << 8) + 'R'),
        /// <summary>
        /// ATIAコマンド
        /// </summary>
        IA = (ushort)(('I' << 8) + 'A'),
        /// <summary>
        /// ATT7コマンド
        /// </summary>
        T7 = (ushort)(('T' << 8) + '7'),
        /// <summary>
        /// ATT6コマンド
        /// </summary>
        T6 = (ushort)(('T' << 8) + '6'),
        /// <summary>
        /// ATT5コマンド
        /// </summary>
        T5 = (ushort)(('T' << 8) + '5'),
        /// <summary>
        /// ATT4コマンド
        /// </summary>
        T4 = (ushort)(('T' << 8) + '4'),
        /// <summary>
        /// ATT3コマンド
        /// </summary>
        T3 = (ushort)(('T' << 8) + '3'),
        /// <summary>
        /// ATT2コマンド
        /// </summary>
        T2 = (ushort)(('T' << 8) + '2'),
        /// <summary>
        /// ATT1コマンド
        /// </summary>
        T1 = (ushort)(('T' << 8) + '1'),
        /// <summary>
        /// ATT0コマンド
        /// </summary>
        T0 = (ushort)(('T' << 8) + '0'),
        /// <summary>
        /// ATP0コマンド
        /// </summary>
        P0 = (ushort)(('P' << 8) + '0'),
        /// <summary>
        /// ATP1コマンド
        /// </summary>
        P1 = (ushort)(('P' << 8) + '1'),
        /// <summary>
        /// ATM0コマンド
        /// </summary>
        M0 = (ushort)(('M' << 8) + '0'),
        /// <summary>
        /// ATM1コマンド
        /// </summary>
        M1 = (ushort)(('M' << 8) + '1'),
        /// <summary>
        /// ATPTコマンド
        /// </summary>
        PT = (ushort)(('P' << 8) + 'T'),
        /// <summary>
        /// ATRPコマンド
        /// </summary>
        RP = (ushort)(('R' << 8) + 'P'),
        /// <summary>
        /// ATVRコマンド
        /// </summary>
        VR = (ushort)(('V' << 8) + 'R'),
        //VL = (ushort)(('V' << 8) + 'L'),//エラーが帰ってくるので封印
        /// <summary>
        /// ATHVコマンド
        /// </summary>
        HV = (ushort)(('H' << 8) + 'V'),
        /// <summary>
        /// ATDBコマンド
        /// </summary>
        DB = (ushort)(('D' << 8) + 'B'),
        /// <summary>
        /// ATECコマンド
        /// </summary>
        EC = (ushort)(('E' << 8) + 'C'),
        /// <summary>
        /// ATEAコマンド
        /// </summary>
        EA = (ushort)(('E' << 8) + 'A'),
        /// <summary>
        /// ATCTコマンド
        /// </summary>
        CT = (ushort)(('C' << 8) + 'T'),
        /// <summary>
        /// ATCNコマンド
        /// </summary>
        CN = (ushort)(('C' << 8) + 'N'),
        /// <summary>
        /// ATACコマンド
        /// </summary>
        AC = (ushort)(('A' << 8) + 'C'),//設定を保存するコマンド
        /// <summary>
        /// ATGTコマンド
        /// </summary>
        GT = (ushort)(('G' << 8) + 'T'),
        /// <summary>
        /// ATCCコマンド
        /// </summary>
        CC = (ushort)(('C' << 8) + 'C')
    }
}
